Derived Custom Class |
|
A derived custom class is a combination of one or more standard classes. For derived custom classes, WS-AppServer generates the read and update methods, which handle data exchange from the Java layer to the database. Unlike pure custom classes where you need to implement the read and write methods and handle its events, a derived custom class provides a default persistence mapping.
A derived custom class is of two types:
- Flattened
- Nested
Flattened Derived Custom Class
A flattened derived custom class has all the attributes at a single level. The attributes may be derived from one or more standard classes. Given below is the database design followed by the object layout of the custom class.
<CourseFull derived="XASTest::Course"> <!-- XASTest represents the package and Course represents the base class --> <CourseID>CourseID</CourseID> <!-- CourseID is the attribute of the base class --> <CourseNotes>Notes</CourseNotes> <PrimaryTeacher>Teacher1</PrimaryTeacher> <PrimaryTeacherName>Teacher1Object.Teacher</PrimaryTeacherName> <PrimaryTeacherNotes>Teacher1Object.Notes</PrimaryTeacherNotes> <SecondaryTeacher>Teacher2</SecondaryTeacher> <SecondaryTeacherName>Teacher2Object.Teacher</SecondaryTeacherName> <SecondaryTeacherNotes>Teacher2Object.Notes</SecondaryTeacherNotes> <ClassRoomBuilding>Building</ClassRoomBuilding> <ClassRoomNr>RoomNr</ClassRoomNr> <ExtraInt>i4</ExtraInt> <ExtraString>string</ExtraString> </CourseFull>
where,
- XASTest represents the package and Course represents the base class.
- CourseID, Notes, Teacher1, Teacher2, Building, and RoomNr are the attributes of the base class.
- Teacher1Object and Teacher2Object are the relationships between the Course and Teacher class.
- Teacher and Notes are the attributes of Teacher class.
- ExtraInt and ExtraString are the custom attributes.
Note:
- It is not necessary to map all the attributes from the base class (as shown in the sample above).
- Unique attributes from the base class (primary key) will remain unique in the derived class, even if it is not explicitly specified. However, if you include any custom attribute that is unique, and at the same time you want to retain the base class attribute as unique, you have to specify it. Otherwise, making a custom attribute as unique will negate the uniqueness of the base class attribute. You can mark an attribute as unique in the attribute properties sheet on the Create Class from Object Layout interface.
Nested Derived Custom Class
A nested derived custom class has all the attributes structured in a nested manner. The attributes may be derived from one or more standard classes. Given below is object layout of the custom class, which is based on the database design shown earlier in this topic.
Note: WS-AppServer does not support repetitive class names in nested classes. However, attributes can repeat across nested classes.
<CourseFull2 derived="XASTest::Course"> <CourseID>CourseID</CourseID> <CourseNotes>Notes</CourseNotes> <PrimaryTeacher>Teacher1</PrimaryTeacher> <PrimaryTeacherData derived="Teacher" derivedRelation="Teacher1Object"> <Name>Teacher</Name> <Notes1>Notes</Notes1> </PrimaryTeacherData> <SecondaryTeacher>Teacher2</SecondaryTeacher> <SecondaryTeacherData derived="Teacher" derivedRelation="Teacher2Object"> <Name>Teacher</Name> <Notes2>Notes</Notes2> </SecondaryTeacherData> <ClassRoomBuilding>Building</ClassRoomBuilding> <ClassRoomNr>RoomNr</ClassRoomNr> <ClassRoom derived="ClassRoom" derivedRelation="BuildingRoomNrObject"> <ClassRoomNotes>Notes</ClassRoomNotes> </ClassRoom> </CourseFull2>
Note: If a derived custom class (derived from several other derived classes) has unmapped attributes (attributes that are not derived from the attributes of a parent class), WS-AppServer generates a query in the Base class of the Java code with appropriate comments to initialize the unmapped attributes in the Extension class. For example, consider the following derived custom class.
Object Layout | Class Type |
---|---|
<Department> <Dept_Id>i4</Dept_Id> <Dept_Name>string</Dept_Name> <location_id>i4</location_id> </Department> |
Standard class |
<D1 derived="Standard::Department"> <custom_field_d1>string</custom_field_d1> <!--Custom attribute that is not derived from the base class --> <custom_field_d2 unique="true">string</custom_field_d2> <!--Unique custom attribute that is not derived from the base class --> <Dept_Id1>Dept_Id</Dept_Id1> <Dept_Name1>Dept_Name</Dept_Name1> <location_id1>location_id</location_id1> </D1> |
Derived Custom class |
In the object layout of the Derived custom class,
custom_field_d1 and
custom_field_d2 are unmapped attributes. The GetD1Object(s) methods of the generated Java source (Base class) will contain the following message for initializing unmapped attribute(s):
public static com.complexcustom.D1 getD1Object(int Dept_Id1) { . // The default code generated by the WS-AppServer framework will be positioned // here. . // The following attributes needs to be initialized. // User is advised to do any customization in the extension class: // custom_field_d1 // custom_field_d2 . return aD1; }
The following sample demonstrates how the Extension class is customized to initialize the unmapped attributes.
/* This class has been generated by the Code Generator */ package com.complexcustom; import com.cordys.cpc.bsf.busobject.BusObject; import com.cordys.cpc.bsf.busobject.BusObjectConfig; import com.cordys.cpc.bsf.busobject.BusObjectIterator; public class D1 extends D1Base { public D1() { this((BusObjectConfig) null); } public D1(BusObjectConfig config) { super(config); } public static D1 getD1Object(int Dept_Id1) { D1 aD1 = D1Base.getD1Object(Dept_Id1); // Here the unmapped attributes are initialized to null if (aD1 != null) { aD1.setNull("custom_field_d1", IGNORE_EVENTS); aD1.setNull("custom_field_d2", IGNORE_EVENTS); } return aD1; } public static BusObjectIterator getD1Objects(int fromDept_Id1, int toDept_Id1) { BusObjectIterator itr = D1Base.getD1Objects(fromDept_Id1, toDept_Id1); if (itr != null) { while (itr.hasMoreElements()) { BusObject bo = itr.nextElement(); if (bo != null) { bo.setNull("custom_field_d1", IGNORE_EVENTS); bo.setNull("custom_field_d2", IGNORE_EVENTS); } } return itr.elements(); } return itr; } public static BusObjectIterator getNextD1Objects(int Dept_Id1, com.cordys.cpc.bsf.query.Cursor cursor) { BusObjectIterator itr = D1Base.getNextD1Objects(Dept_Id1, cursor); if (itr != null) { while (itr.hasMoreElements()) { BusObject bo = itr.nextElement(); if (bo != null) { bo.setNull("custom_field_d1", IGNORE_EVENTS); bo.setNull("custom_field_d2", IGNORE_EVENTS); } } return itr.elements(); } return itr; } public static BusObjectIterator getPreviousD1Objects(int Dept_Id1, com.cordys.cpc.bsf.query.Cursor cursor) { BusObjectIterator itr = D1Base.getPreviousD1Objects(Dept_Id1, cursor); if (itr != null) { while (itr.hasMoreElements()) { BusObject bo = itr.nextElement(); if (bo != null) { bo.setNull("custom_field_d1", IGNORE_EVENTS); bo.setNull("custom_field_d2", IGNORE_EVENTS); } } return itr.elements(); } return itr; } }
Note: While creating a derived class from object layout, if the root class is of type Custom (any of the custom formats - Derived, Query, or Pure Custom), the GetXXXObject(s) method implementation in the generated source will be empty. This condition also applies to a derived class that has unique attributes but which are not derived from a base class. For such methods, you will need to provide additional logic to retrieve necessary data.